(function (modules) {
  // 14.合并模块定义，改变promise状态
  function webpackJsonpCallback(data) {
    // 获取需要被动态加载的模块id
    let chunkIds = data[0]
    // 获取需要被动态加载的模块依赖关系
    let moreModules = data[1]
    let chunkId, resolves = []
    // 循环判断chunkIds里对应的模块内容是否已经加载完
    for (let i = 0; i < chunkIds.length; i++) {
      chunkId = chunkIds[i]
      if (Object.prototype.hasOwnProperty.call(inStalledChunks, chunkId) && inStalledChunks[chunkId]) {
        resolves.push(inStalledChunks[chunkId][0])
      }
      // 更新当前chunk状态
      inStalledChunks[chunkId] = 0
    }

    for (moduleId in moreModules) {
      if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
        modules[moduleId] = moreModules[moduleId]
      }
    }

    while (resolves.length) {
      resolves.shift()()
    }
  }

  // 1.定义对象用于将来缓存被加载过的模块
  let installedModules = {}

  // 15.用于标识某个chunkId对应的chunk是否完成了加载
  let inStalledChunks = {
    main: 0
  }

  // 2.定义__webpack_require__方法来替换import require加载操作
  function __webpack_require__(moduleId) {
    // 2-1.判断当前缓存中是否存在要被加载的模块内容，如果存在则直接返回
    if (installedModules[moduleId]) {
      return installedModules[moduleId].exports
    }

    // 2-2.如果当前缓存中不存在则需要我们自己定义{}执行被导入的模块内容加载
    let module = installedModules[moduleId] = {
      i: moduleId,
      l: false,
      exports: {}
    }

    // 2-3.调用当前moduleId对应的函数，然后完成内容的加载
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)


    // 2-4.当上述的方法调用完成之后，我们可以修改l的值用于表示当前模块内容已经加载完成
    module.l = true

    // 2-5.加载工作完成之后，要将拿回来的内容返回至调用的位置
    return module.exports
  }

  // 3.定义m属性用于保存modules 
  __webpack_require__.m = modules

  // 4.定义c属性用于保存cache
  __webpack_require__.c = installedModules

  // 5.定义o方法用于判断对象身上是否存在指定的属性
  __webpack_require__.o = function (object, property) {
    return Object.prototype.hasOwnProperty(object, property)
  }

  // 6.定义d方法用于在对象的身上添加指定的属性，同时给该属性提供一个getter
  __webpack_require__.d = function (exports, name, getter) {
    if (!__webpack_require__.o(exports, name)) {
      Object.defineProperty(exports, name, { enumerable: true, get: getter })
    }
  }

  // 7.定义r方法用于标识当前模块是es6类型
  __webpack_require__.r = function (exports) {
    if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
      Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
    }
    Object.defineProperty(exports, "__esModule", { value: true });
  }

  // 8.定义n方法,用于设置具体的getter
  __webpack_require__.n = function (module) {
    let getter = module && module.__esModule ?
      function getDefault() { return module['default'] } :
      function getModuleExports() { return module; }
    __webpack_require__.d(getter, 'a', getter)
    return getter;
  }

  // 17.定义jsonpScriptSrc实现src的处理
  function jsonpScriptSrc(chunkId) {
    return __webpack_require__.p + "" + chunkId + '.bundle.js'
  }

  // 16.定义e方法实现json来加载内容，利用promise来实现异步加载操作
  __webpack_require__.e = function (chunkId) {
    // 定义数组存放promise
    let promises = []

    // 获取chunkId对应的chunk是否完成加载
    let installedChunkData = inStalledChunks[chunkId]

    // 依据当前是否已完成加载的状态来执行后续的逻辑
    if (installedChunkData !== 0) {
      if (installedChunkData) {
        promises.push(installedChunkData[2])
      } else {
        let promise = new Promise((resolve, reject) => {
          installedChunkData = inStalledChunks[chunkId] = [resolve, reject]
        })
        promises.push(installedChunkData[2] = promise)

        let script = document.createElement('script')

        script.src = jsonpScriptSrc(chunkId)

        document.head.appendChild(script)
      }
    }

    return Promise.all(promises)
  }

  // 11.定义t方法，用于加载指定value模块，之后对内容进行处理返回
  __webpack_require__.t = function (value, mode) {
    if (mode & 1) {// 使用自定义加载
      value = __webpack_require__(value)
    }
    if (mode & 8) {// 加载了可以直接返回使用内容，commonJs规范
      return value
    }

    // esModule规范
    if ((mode & 4) && typeof value === 'object' && value && value.__esModule) {
      return value
    }

    let ns = Object.create(null)

    __webpack_require__.r(ns)

    Object.defineProperty(ns, 'default', { enumerable: true, value: value })

    if (mode & 2 && typeof value !== 'string') {
      for (var key in value) {
        __webpack_require__.d(ns, key, function (key) {
          return value[key]
        }.bind(null, key))
      }
    }

    return ns
  }

  // 9.定义p属性用于保存资源访问路径
  __webpack_require__.p = ''

  // 11.定义变量存放数组
  let jsonpArray = window['webpackJsonp'] = window['webpackJsonp'] || []

  // 12.保存原生的push方法
  let oldJsonpFunction = jsonpArray.push.bind(jsonpArray)

  // 13重写原生的push方法
  jsonpArray.push = webpackJsonpCallback

  // 10.调用__webpack_require__方法执行模块导入与加载操作
  return __webpack_require__(__webpack_require__.s = './src/index.js')
})({
  "./src/index.js":
    (function (module, exports, __webpack_require__) {
      let oBtn = document.getElementById('btn')
      oBtn.addEventListener('click', function () {
        __webpack_require__.e(/*! import() | cms */ "cms")
          .then(__webpack_require__.t.bind(null, /*! ./cms.js */ "./src/cms.js", 7))
          .then(name => {
            console.log(name)
          })
      })
      console.log(`执行了`)
    })
});